From: George Dunlap Date: Wed, 11 Oct 2017 17:49:40 +0000 (+0100) Subject: fuzz/x86_emulate: Rename the file containing the wrapper code X-Git-Tag: archive/raspbian/4.11.1-1+rpi1~1^2~66^2~1111 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22Dat/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22Dat?a=commitdiff_plain;h=4955d680c7510d8d7f72cca990ad2474d71cd662;p=xen.git fuzz/x86_emulate: Rename the file containing the wrapper code When generating coverage output, by default gcov generates output filenames based only on the coverage file and the "leaf" source file, not the full path. As a result, it uses the same name for x86_emulate.c and x86_emulate/x86_emulate.c, generally overwriting the second (which we actually are about) with the first (which is just a wrapper). Rename the user-space wrapper helpers to x86-emulate.[ch], so that it generates separate files. There is actually an option to gcov, `--preserve-paths`, which will cause the full path name to be included in the filename, properly distinguishing between the two. However, given that the user-space wrapper doesn't actually do any emulation (and the poor state of gcov documentation making it difficult to find the option in the first place), it seems to make more sense to rename the file anyway. Signed-off-by: George Dunlap Acked-by: Wei Liu Acked-by: Jan Beulich --- diff --git a/.gitignore b/.gitignore index 95f40f19c8..b3587f3809 100644 --- a/.gitignore +++ b/.gitignore @@ -163,7 +163,8 @@ tools/flask/utils/flask-set-bool tools/flask/utils/flask-label-pci tools/fuzz/libelf/afl-libelf-fuzzer tools/fuzz/x86_instruction_emulator/asm -tools/fuzz/x86_instruction_emulator/x86_emulate* +tools/fuzz/x86_instruction_emulator/x86_emulate +tools/fuzz/x86_instruction_emulator/x86-emulate.[ch] tools/fuzz/x86_instruction_emulator/afl-harness tools/helpers/_paths.h tools/helpers/init-xenstore-domain diff --git a/tools/fuzz/x86_instruction_emulator/Makefile b/tools/fuzz/x86_instruction_emulator/Makefile index a3f6b2c754..107bf62a21 100644 --- a/tools/fuzz/x86_instruction_emulator/Makefile +++ b/tools/fuzz/x86_instruction_emulator/Makefile @@ -18,22 +18,22 @@ asm: asm/%: asm ; -x86_emulate.c x86_emulate.h: %: +x86-emulate.c x86-emulate.h: %: [ -L $* ] || ln -sf $(XEN_ROOT)/tools/tests/x86_emulator/$* CFLAGS += $(CFLAGS_xeninclude) -D__XEN_TOOLS__ -I. x86.h := asm/x86-vendors.h asm/x86-defns.h asm/msr-index.h -x86_emulate.h := x86_emulate.h x86_emulate/x86_emulate.h $(x86.h) +x86_emulate.h := x86-emulate.h x86_emulate/x86_emulate.h $(x86.h) -x86_emulate.o: x86_emulate.c x86_emulate/x86_emulate.c $(x86_emulate.h) +x86-emulate.o: x86-emulate.c x86_emulate/x86_emulate.c $(x86_emulate.h) fuzz-emul.o: $(x86_emulate.h) -x86-insn-fuzzer.a: fuzz-emul.o x86_emulate.o +x86-insn-fuzzer.a: fuzz-emul.o x86-emulate.o $(AR) rc $@ $^ -afl-harness: afl-harness.o fuzz-emul.o x86_emulate.o +afl-harness: afl-harness.o fuzz-emul.o x86-emulate.o $(CC) $(CFLAGS) $^ -o $@ # Common targets @@ -42,7 +42,7 @@ all: x86-insn-fuzz-all .PHONY: distclean distclean: clean - rm -f x86_emulate x86_emulate.c x86_emulate.h asm + rm -f x86_emulate x86-emulate.c x86-emulate.h asm .PHONY: clean clean: diff --git a/tools/fuzz/x86_instruction_emulator/fuzz-emul.c b/tools/fuzz/x86_instruction_emulator/fuzz-emul.c index 5fb8586955..8998f21fe1 100644 --- a/tools/fuzz/x86_instruction_emulator/fuzz-emul.c +++ b/tools/fuzz/x86_instruction_emulator/fuzz-emul.c @@ -15,7 +15,7 @@ #include #include -#include "x86_emulate.h" +#include "x86-emulate.h" #define MSR_INDEX_MAX 16 diff --git a/tools/tests/x86_emulator/Makefile b/tools/tests/x86_emulator/Makefile index d7be77d98a..ed0fd9710e 100644 --- a/tools/tests/x86_emulator/Makefile +++ b/tools/tests/x86_emulator/Makefile @@ -77,7 +77,7 @@ $(addsuffix .h,$(TESTCASES)): %.h: %.c testcase.mk Makefile $(addsuffix .c,$(SIMD)) $(addsuffix -avx.c,$(filter sse%,$(SIMD))): ln -sf simd.c $@ -$(TARGET): x86_emulate.o test_x86_emulator.o +$(TARGET): x86-emulate.o test_x86_emulator.o $(HOSTCC) $(HOSTCFLAGS) -o $@ $^ .PHONY: clean @@ -105,9 +105,9 @@ $(call cc-option-add,HOSTCFLAGS-x86_64,HOSTCC,-no-pie) HOSTCFLAGS += $(CFLAGS_xeninclude) -I. $(HOSTCFLAGS-$(XEN_COMPILE_ARCH)) x86.h := asm/x86-vendors.h asm/x86-defns.h asm/msr-index.h -x86_emulate.h := x86_emulate.h x86_emulate/x86_emulate.h $(x86.h) +x86_emulate.h := x86-emulate.h x86_emulate/x86_emulate.h $(x86.h) -x86_emulate.o: x86_emulate.c x86_emulate/x86_emulate.c $(x86_emulate.h) +x86-emulate.o: x86-emulate.c x86_emulate/x86_emulate.c $(x86_emulate.h) $(HOSTCC) $(HOSTCFLAGS) -D__XEN_TOOLS__ -c -g -o $@ $< test_x86_emulator.o: test_x86_emulator.c $(addsuffix .h,$(TESTCASES)) $(x86_emulate.h) diff --git a/tools/tests/x86_emulator/test_x86_emulator.c b/tools/tests/x86_emulator/test_x86_emulator.c index 2bb4b1e04b..7a8df419cd 100644 --- a/tools/tests/x86_emulator/test_x86_emulator.c +++ b/tools/tests/x86_emulator/test_x86_emulator.c @@ -3,7 +3,7 @@ #include #include -#include "x86_emulate.h" +#include "x86-emulate.h" #include "blowfish.h" #include "sse.h" #include "sse2.h" diff --git a/tools/tests/x86_emulator/x86-emulate.c b/tools/tests/x86_emulator/x86-emulate.c new file mode 100644 index 0000000000..975ddc7e53 --- /dev/null +++ b/tools/tests/x86_emulator/x86-emulate.c @@ -0,0 +1,156 @@ +#include "x86-emulate.h" + +#include + +#define cpu_has_amd_erratum(nr) 0 +#define mark_regs_dirty(r) ((void)(r)) +#define cpu_has_mpx false +#define read_bndcfgu() 0 +#define xstate_set_init(what) + +/* For generic assembly code: use macros to define operation/operand sizes. */ +#ifdef __i386__ +# define r(name) e ## name +# define __OS "l" /* Operation Suffix */ +# define __OP "e" /* Operand Prefix */ +#else +# define r(name) r ## name +# define __OS "q" /* Operation Suffix */ +# define __OP "r" /* Operand Prefix */ +#endif + +#define get_stub(stb) ({ \ + assert(!(stb).addr); \ + (void *)((stb).addr = (uintptr_t)(stb).buf); \ +}) +#define put_stub(stb) ((stb).addr = 0) + +uint32_t mxcsr_mask = 0x0000ffbf; + +bool emul_test_init(void) +{ + unsigned long sp; + + if ( cpu_has_fxsr ) + { + static union __attribute__((__aligned__(16))) { + char x[464]; + struct { + uint32_t other[6]; + uint32_t mxcsr; + uint32_t mxcsr_mask; + /* ... */ + }; + } fxs; + + asm ( "fxsave %0" : "=m" (fxs) ); + if ( fxs.mxcsr_mask ) + mxcsr_mask = fxs.mxcsr_mask; + } + + /* + * Mark the entire stack executable so that the stub executions + * don't fault + */ +#ifdef __x86_64__ + asm ("movq %%rsp, %0" : "=g" (sp)); +#else + asm ("movl %%esp, %0" : "=g" (sp)); +#endif + + return mprotect((void *)(sp & -0x1000L) - (MMAP_SZ - 0x1000), + MMAP_SZ, PROT_READ|PROT_WRITE|PROT_EXEC) == 0; +} + +int emul_test_cpuid( + uint32_t leaf, + uint32_t subleaf, + struct cpuid_leaf *res, + struct x86_emulate_ctxt *ctxt) +{ + asm ("cpuid" + : "=a" (res->a), "=b" (res->b), "=c" (res->c), "=d" (res->d) + : "a" (leaf), "c" (subleaf)); + + /* + * The emulator doesn't itself use MOVBE, so we can always run the + * respective tests. + */ + if ( leaf == 1 ) + res->c |= 1U << 22; + + /* + * The emulator doesn't itself use ADCX/ADOX/RDPID, so we can always run + * the respective tests. + */ + if ( leaf == 7 && subleaf == 0 ) + { + res->b |= 1U << 19; + res->c |= 1U << 22; + } + + /* + * The emulator doesn't itself use CLZERO, so we can always run the + * respective test(s). + */ + if ( leaf == 0x80000008 ) + res->b |= 1U << 0; + + return X86EMUL_OKAY; +} + +int emul_test_read_cr( + unsigned int reg, + unsigned long *val, + struct x86_emulate_ctxt *ctxt) +{ + /* Fake just enough state for the emulator's _get_fpu() to be happy. */ + switch ( reg ) + { + case 0: + *val = 0x00000001; /* PE */ + return X86EMUL_OKAY; + + case 4: + /* OSFXSR, OSXMMEXCPT, and maybe OSXSAVE */ + *val = 0x00000600 | (cpu_has_xsave ? 0x00040000 : 0); + return X86EMUL_OKAY; + } + + return X86EMUL_UNHANDLEABLE; +} + +int emul_test_get_fpu( + void (*exception_callback)(void *, struct cpu_user_regs *), + void *exception_callback_arg, + enum x86_emulate_fpu_type type, + struct x86_emulate_ctxt *ctxt) +{ + switch ( type ) + { + case X86EMUL_FPU_fpu: + break; + case X86EMUL_FPU_mmx: + if ( cpu_has_mmx ) + break; + case X86EMUL_FPU_xmm: + if ( cpu_has_sse ) + break; + case X86EMUL_FPU_ymm: + if ( cpu_has_avx ) + break; + default: + return X86EMUL_UNHANDLEABLE; + } + return X86EMUL_OKAY; +} + +void emul_test_put_fpu( + struct x86_emulate_ctxt *ctxt, + enum x86_emulate_fpu_type backout, + const struct x86_emul_fpu_aux *aux) +{ + /* TBD */ +} + +#include "x86_emulate/x86_emulate.c" diff --git a/tools/tests/x86_emulator/x86-emulate.h b/tools/tests/x86_emulator/x86-emulate.h new file mode 100644 index 0000000000..b90101004f --- /dev/null +++ b/tools/tests/x86_emulator/x86-emulate.h @@ -0,0 +1,185 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define BUG() abort() +#define ASSERT assert +#define ASSERT_UNREACHABLE() assert(!__LINE__) + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) +/* Force a compilation error if condition is true */ +#define BUILD_BUG_ON(cond) ({ _Static_assert(!(cond), "!(" #cond ")"); }) +#define BUILD_BUG_ON_ZERO(cond) \ + sizeof(struct { _Static_assert(!(cond), "!(" #cond ")"); }) +#else +#define BUILD_BUG_ON_ZERO(cond) sizeof(struct { int:-!!(cond); }) +#define BUILD_BUG_ON(cond) ((void)BUILD_BUG_ON_ZERO(cond)) +#endif + +#define MASK_EXTR(v, m) (((v) & (m)) / ((m) & -(m))) +#define MASK_INSR(v, m) (((v) * ((m) & -(m))) & (m)) + +#define __init +#define __maybe_unused __attribute__((__unused__)) + +#define likely(x) __builtin_expect(!!(x), true) +#define unlikely(x) __builtin_expect(!!(x), false) + +#define container_of(ptr, type, member) ({ \ + typeof(((type *)0)->member) *mptr__ = (ptr); \ + (type *)((char *)mptr__ - offsetof(type, member)); \ +}) + +#define is_canonical_address(x) (((int64_t)(x) >> 47) == ((int64_t)(x) >> 63)) + +extern uint32_t mxcsr_mask; + +#define MMAP_SZ 16384 +bool emul_test_init(void); + +#include "x86_emulate/x86_emulate.h" + +static inline uint64_t xgetbv(uint32_t xcr) +{ + uint32_t lo, hi; + + asm ( ".byte 0x0f, 0x01, 0xd0" : "=a" (lo), "=d" (hi) : "c" (xcr) ); + + return ((uint64_t)hi << 32) | lo; +} + +#define cache_line_size() ({ \ + struct cpuid_leaf res; \ + emul_test_cpuid(1, 0, &res, NULL); \ + res.d & (1U << 19) ? (res.b >> 5) & 0x7f8 : 0; \ +}) + +#define cpu_has_mmx ({ \ + struct cpuid_leaf res; \ + emul_test_cpuid(1, 0, &res, NULL); \ + (res.d & (1U << 23)) != 0; \ +}) + +#define cpu_has_fxsr ({ \ + struct cpuid_leaf res; \ + emul_test_cpuid(1, 0, &res, NULL); \ + (res.d & (1U << 24)) != 0; \ +}) + +#define cpu_has_sse ({ \ + struct cpuid_leaf res; \ + emul_test_cpuid(1, 0, &res, NULL); \ + (res.d & (1U << 25)) != 0; \ +}) + +#define cpu_has_sse2 ({ \ + struct cpuid_leaf res; \ + emul_test_cpuid(1, 0, &res, NULL); \ + (res.d & (1U << 26)) != 0; \ +}) + +#define cpu_has_sse3 ({ \ + struct cpuid_leaf res; \ + emul_test_cpuid(1, 0, &res, NULL); \ + (res.c & (1U << 0)) != 0; \ +}) + +#define cpu_has_sse4_1 ({ \ + struct cpuid_leaf res; \ + emul_test_cpuid(1, 0, &res, NULL); \ + (res.c & (1U << 19)) != 0; \ +}) + +#define cpu_has_sse4_2 ({ \ + struct cpuid_leaf res; \ + emul_test_cpuid(1, 0, &res, NULL); \ + (res.c & (1U << 20)) != 0; \ +}) + +#define cpu_has_popcnt ({ \ + struct cpuid_leaf res; \ + emul_test_cpuid(1, 0, &res, NULL); \ + (res.c & (1U << 23)) != 0; \ +}) + +#define cpu_has_xsave ({ \ + struct cpuid_leaf res; \ + emul_test_cpuid(1, 0, &res, NULL); \ + /* Intentionally checking OSXSAVE here. */ \ + (res.c & (1U << 27)) != 0; \ +}) + +#define cpu_has_avx ({ \ + struct cpuid_leaf res; \ + emul_test_cpuid(1, 0, &res, NULL); \ + if ( !(res.c & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \ + res.c = 0; \ + (res.c & (1U << 28)) != 0; \ +}) + +#define cpu_has_avx2 ({ \ + struct cpuid_leaf res; \ + emul_test_cpuid(1, 0, &res, NULL); \ + if ( !(res.c & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \ + res.b = 0; \ + else { \ + emul_test_cpuid(7, 0, &res, NULL); \ + } \ + (res.b & (1U << 5)) != 0; \ +}) + +#define cpu_has_bmi1 ({ \ + struct cpuid_leaf res; \ + emul_test_cpuid(7, 0, &res, NULL); \ + (res.b & (1U << 3)) != 0; \ +}) + +#define cpu_has_bmi2 ({ \ + struct cpuid_leaf res; \ + emul_test_cpuid(7, 0, &res, NULL); \ + (res.b & (1U << 8)) != 0; \ +}) + +#define cpu_has_sse4a ({ \ + struct cpuid_leaf res; \ + emul_test_cpuid(0x80000001, 0, &res, NULL); \ + (res.c & (1U << 6)) != 0; \ +}) + +#define cpu_has_tbm ({ \ + struct cpuid_leaf res; \ + emul_test_cpuid(0x80000001, 0, &res, NULL); \ + (res.c & (1U << 21)) != 0; \ +}) + +int emul_test_cpuid( + uint32_t leaf, + uint32_t subleaf, + struct cpuid_leaf *res, + struct x86_emulate_ctxt *ctxt); + +int emul_test_read_cr( + unsigned int reg, + unsigned long *val, + struct x86_emulate_ctxt *ctxt); + +int emul_test_get_fpu( + void (*exception_callback)(void *, struct cpu_user_regs *), + void *exception_callback_arg, + enum x86_emulate_fpu_type type, + struct x86_emulate_ctxt *ctxt); + +void emul_test_put_fpu( + struct x86_emulate_ctxt *ctxt, + enum x86_emulate_fpu_type backout, + const struct x86_emul_fpu_aux *aux); diff --git a/tools/tests/x86_emulator/x86_emulate.c b/tools/tests/x86_emulator/x86_emulate.c deleted file mode 100644 index 79661d5c2b..0000000000 --- a/tools/tests/x86_emulator/x86_emulate.c +++ /dev/null @@ -1,156 +0,0 @@ -#include "x86_emulate.h" - -#include - -#define cpu_has_amd_erratum(nr) 0 -#define mark_regs_dirty(r) ((void)(r)) -#define cpu_has_mpx false -#define read_bndcfgu() 0 -#define xstate_set_init(what) - -/* For generic assembly code: use macros to define operation/operand sizes. */ -#ifdef __i386__ -# define r(name) e ## name -# define __OS "l" /* Operation Suffix */ -# define __OP "e" /* Operand Prefix */ -#else -# define r(name) r ## name -# define __OS "q" /* Operation Suffix */ -# define __OP "r" /* Operand Prefix */ -#endif - -#define get_stub(stb) ({ \ - assert(!(stb).addr); \ - (void *)((stb).addr = (uintptr_t)(stb).buf); \ -}) -#define put_stub(stb) ((stb).addr = 0) - -uint32_t mxcsr_mask = 0x0000ffbf; - -bool emul_test_init(void) -{ - unsigned long sp; - - if ( cpu_has_fxsr ) - { - static union __attribute__((__aligned__(16))) { - char x[464]; - struct { - uint32_t other[6]; - uint32_t mxcsr; - uint32_t mxcsr_mask; - /* ... */ - }; - } fxs; - - asm ( "fxsave %0" : "=m" (fxs) ); - if ( fxs.mxcsr_mask ) - mxcsr_mask = fxs.mxcsr_mask; - } - - /* - * Mark the entire stack executable so that the stub executions - * don't fault - */ -#ifdef __x86_64__ - asm ("movq %%rsp, %0" : "=g" (sp)); -#else - asm ("movl %%esp, %0" : "=g" (sp)); -#endif - - return mprotect((void *)(sp & -0x1000L) - (MMAP_SZ - 0x1000), - MMAP_SZ, PROT_READ|PROT_WRITE|PROT_EXEC) == 0; -} - -int emul_test_cpuid( - uint32_t leaf, - uint32_t subleaf, - struct cpuid_leaf *res, - struct x86_emulate_ctxt *ctxt) -{ - asm ("cpuid" - : "=a" (res->a), "=b" (res->b), "=c" (res->c), "=d" (res->d) - : "a" (leaf), "c" (subleaf)); - - /* - * The emulator doesn't itself use MOVBE, so we can always run the - * respective tests. - */ - if ( leaf == 1 ) - res->c |= 1U << 22; - - /* - * The emulator doesn't itself use ADCX/ADOX/RDPID, so we can always run - * the respective tests. - */ - if ( leaf == 7 && subleaf == 0 ) - { - res->b |= 1U << 19; - res->c |= 1U << 22; - } - - /* - * The emulator doesn't itself use CLZERO, so we can always run the - * respective test(s). - */ - if ( leaf == 0x80000008 ) - res->b |= 1U << 0; - - return X86EMUL_OKAY; -} - -int emul_test_read_cr( - unsigned int reg, - unsigned long *val, - struct x86_emulate_ctxt *ctxt) -{ - /* Fake just enough state for the emulator's _get_fpu() to be happy. */ - switch ( reg ) - { - case 0: - *val = 0x00000001; /* PE */ - return X86EMUL_OKAY; - - case 4: - /* OSFXSR, OSXMMEXCPT, and maybe OSXSAVE */ - *val = 0x00000600 | (cpu_has_xsave ? 0x00040000 : 0); - return X86EMUL_OKAY; - } - - return X86EMUL_UNHANDLEABLE; -} - -int emul_test_get_fpu( - void (*exception_callback)(void *, struct cpu_user_regs *), - void *exception_callback_arg, - enum x86_emulate_fpu_type type, - struct x86_emulate_ctxt *ctxt) -{ - switch ( type ) - { - case X86EMUL_FPU_fpu: - break; - case X86EMUL_FPU_mmx: - if ( cpu_has_mmx ) - break; - case X86EMUL_FPU_xmm: - if ( cpu_has_sse ) - break; - case X86EMUL_FPU_ymm: - if ( cpu_has_avx ) - break; - default: - return X86EMUL_UNHANDLEABLE; - } - return X86EMUL_OKAY; -} - -void emul_test_put_fpu( - struct x86_emulate_ctxt *ctxt, - enum x86_emulate_fpu_type backout, - const struct x86_emul_fpu_aux *aux) -{ - /* TBD */ -} - -#include "x86_emulate/x86_emulate.c" diff --git a/tools/tests/x86_emulator/x86_emulate.h b/tools/tests/x86_emulator/x86_emulate.h deleted file mode 100644 index b90101004f..0000000000 --- a/tools/tests/x86_emulator/x86_emulate.h +++ /dev/null @@ -1,185 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define BUG() abort() -#define ASSERT assert -#define ASSERT_UNREACHABLE() assert(!__LINE__) - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) - -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) -/* Force a compilation error if condition is true */ -#define BUILD_BUG_ON(cond) ({ _Static_assert(!(cond), "!(" #cond ")"); }) -#define BUILD_BUG_ON_ZERO(cond) \ - sizeof(struct { _Static_assert(!(cond), "!(" #cond ")"); }) -#else -#define BUILD_BUG_ON_ZERO(cond) sizeof(struct { int:-!!(cond); }) -#define BUILD_BUG_ON(cond) ((void)BUILD_BUG_ON_ZERO(cond)) -#endif - -#define MASK_EXTR(v, m) (((v) & (m)) / ((m) & -(m))) -#define MASK_INSR(v, m) (((v) * ((m) & -(m))) & (m)) - -#define __init -#define __maybe_unused __attribute__((__unused__)) - -#define likely(x) __builtin_expect(!!(x), true) -#define unlikely(x) __builtin_expect(!!(x), false) - -#define container_of(ptr, type, member) ({ \ - typeof(((type *)0)->member) *mptr__ = (ptr); \ - (type *)((char *)mptr__ - offsetof(type, member)); \ -}) - -#define is_canonical_address(x) (((int64_t)(x) >> 47) == ((int64_t)(x) >> 63)) - -extern uint32_t mxcsr_mask; - -#define MMAP_SZ 16384 -bool emul_test_init(void); - -#include "x86_emulate/x86_emulate.h" - -static inline uint64_t xgetbv(uint32_t xcr) -{ - uint32_t lo, hi; - - asm ( ".byte 0x0f, 0x01, 0xd0" : "=a" (lo), "=d" (hi) : "c" (xcr) ); - - return ((uint64_t)hi << 32) | lo; -} - -#define cache_line_size() ({ \ - struct cpuid_leaf res; \ - emul_test_cpuid(1, 0, &res, NULL); \ - res.d & (1U << 19) ? (res.b >> 5) & 0x7f8 : 0; \ -}) - -#define cpu_has_mmx ({ \ - struct cpuid_leaf res; \ - emul_test_cpuid(1, 0, &res, NULL); \ - (res.d & (1U << 23)) != 0; \ -}) - -#define cpu_has_fxsr ({ \ - struct cpuid_leaf res; \ - emul_test_cpuid(1, 0, &res, NULL); \ - (res.d & (1U << 24)) != 0; \ -}) - -#define cpu_has_sse ({ \ - struct cpuid_leaf res; \ - emul_test_cpuid(1, 0, &res, NULL); \ - (res.d & (1U << 25)) != 0; \ -}) - -#define cpu_has_sse2 ({ \ - struct cpuid_leaf res; \ - emul_test_cpuid(1, 0, &res, NULL); \ - (res.d & (1U << 26)) != 0; \ -}) - -#define cpu_has_sse3 ({ \ - struct cpuid_leaf res; \ - emul_test_cpuid(1, 0, &res, NULL); \ - (res.c & (1U << 0)) != 0; \ -}) - -#define cpu_has_sse4_1 ({ \ - struct cpuid_leaf res; \ - emul_test_cpuid(1, 0, &res, NULL); \ - (res.c & (1U << 19)) != 0; \ -}) - -#define cpu_has_sse4_2 ({ \ - struct cpuid_leaf res; \ - emul_test_cpuid(1, 0, &res, NULL); \ - (res.c & (1U << 20)) != 0; \ -}) - -#define cpu_has_popcnt ({ \ - struct cpuid_leaf res; \ - emul_test_cpuid(1, 0, &res, NULL); \ - (res.c & (1U << 23)) != 0; \ -}) - -#define cpu_has_xsave ({ \ - struct cpuid_leaf res; \ - emul_test_cpuid(1, 0, &res, NULL); \ - /* Intentionally checking OSXSAVE here. */ \ - (res.c & (1U << 27)) != 0; \ -}) - -#define cpu_has_avx ({ \ - struct cpuid_leaf res; \ - emul_test_cpuid(1, 0, &res, NULL); \ - if ( !(res.c & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \ - res.c = 0; \ - (res.c & (1U << 28)) != 0; \ -}) - -#define cpu_has_avx2 ({ \ - struct cpuid_leaf res; \ - emul_test_cpuid(1, 0, &res, NULL); \ - if ( !(res.c & (1U << 27)) || ((xgetbv(0) & 6) != 6) ) \ - res.b = 0; \ - else { \ - emul_test_cpuid(7, 0, &res, NULL); \ - } \ - (res.b & (1U << 5)) != 0; \ -}) - -#define cpu_has_bmi1 ({ \ - struct cpuid_leaf res; \ - emul_test_cpuid(7, 0, &res, NULL); \ - (res.b & (1U << 3)) != 0; \ -}) - -#define cpu_has_bmi2 ({ \ - struct cpuid_leaf res; \ - emul_test_cpuid(7, 0, &res, NULL); \ - (res.b & (1U << 8)) != 0; \ -}) - -#define cpu_has_sse4a ({ \ - struct cpuid_leaf res; \ - emul_test_cpuid(0x80000001, 0, &res, NULL); \ - (res.c & (1U << 6)) != 0; \ -}) - -#define cpu_has_tbm ({ \ - struct cpuid_leaf res; \ - emul_test_cpuid(0x80000001, 0, &res, NULL); \ - (res.c & (1U << 21)) != 0; \ -}) - -int emul_test_cpuid( - uint32_t leaf, - uint32_t subleaf, - struct cpuid_leaf *res, - struct x86_emulate_ctxt *ctxt); - -int emul_test_read_cr( - unsigned int reg, - unsigned long *val, - struct x86_emulate_ctxt *ctxt); - -int emul_test_get_fpu( - void (*exception_callback)(void *, struct cpu_user_regs *), - void *exception_callback_arg, - enum x86_emulate_fpu_type type, - struct x86_emulate_ctxt *ctxt); - -void emul_test_put_fpu( - struct x86_emulate_ctxt *ctxt, - enum x86_emulate_fpu_type backout, - const struct x86_emul_fpu_aux *aux);